program _2DGraphics;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  SampleCommon,
  DIrr in '..\..\DSource\DIrr.pas',
  DIrr.Consts in '..\..\DSource\DIrr.Consts.pas',
  DIrr.Rect in '..\..\DSource\DIrr.Rect.pas',
  DIrr.GUI in '..\..\DSource\DIrr.GUI.pas',
  DIrr.Color in '..\..\DSource\DIrr.Color.pas',
  DIrr.Event in '..\..\DSource\DIrr.Event.pas',
  DIrr.Vector2D in '..\..\DSource\DIrr.Vector2D.pas',
  DIrr.Vector3D in '..\..\DSource\DIrr.Vector3D.pas',
  DIrr.Video in '..\..\DSource\DIrr.Video.pas',
  DIrr.Base in '..\..\DSource\DIrr.Base.pas',
  DIrr.Types in '..\..\DSource\DIrr.Types.pas',
  DIrr.Scene in '..\..\DSource\DIrr.Scene.pas',
  DIrr.Structs in '..\..\DSource\DIrr.Structs.pas',
  DIrr.Aabbox3D in '..\..\DSource\DIrr.Aabbox3D.pas',
  DIrr.Matrix4 in '..\..\DSource\DIrr.Matrix4.pas',
  DIrr.Texture in '..\..\DSource\DIrr.Texture.pas',
  DIrr.Dimension2d in '..\..\DSource\DIrr.Dimension2d.pas',
  DIrr.Collections in '..\..\DSource\DIrr.Collections.pas';

var
  DriverType: E_DRIVER_TYPE;
  Device: TIrrlichtDevice;
  Driver: TVideoDriver;
  Images: TTexture;
  Font, Font2: TGUIFont;
  Imp1: TIrrRect = (
                     UpperLeftCorner : (X : 349; Y : 15);
                     LowerRightCorner : (X : 385; Y : 78)
                   );
  Imp2: TIrrRect = (
                     UpperLeftCorner : (X : 387; Y : 15);
                     LowerRightCorner : (X : 423; Y : 78)
                   );
  ImpPtr: PIrrRect;

  //ClipRect: TIrrRect;
  MaterialPtr: PMaterial;
  time: u32;
  m: TVector2D;
begin
  try
    DriverType := DriverChoiceConsole;
    if DriverType = EDT_COUNT then
    begin
      ExitCode := 1;
      Exit;
    end;

    // create device
    Device := CreateDevice(DriverType, [512, 384]);
    if Device = nil then
    begin
      ExitCode := 1;   // could not create selected driver.
      Exit;
    end;

    Device.SetWindowCaption('Irrlicht Engine - 2D Graphics Demo');
    Driver := Device.GetVideoDriver;

    (*
    All 2d graphics in this example are put together into one texture,
    2ddemo.png. Because we want to draw colorkey based sprites, we need to
    load this texture and tell the engine, which part of it should be
    transparent based on a colorkey.

    In this example, we don't tell it the color directly, we just say "Hey
    Irrlicht Engine, you'll find the color I want at position (0,0) on the
    texture.". Instead, it would be also possible to call
    driver->makeColorKeyTexture(images, video::SColor(0,0,0,0)), to make
    e.g. all black pixels transparent. Please note that
    makeColorKeyTexture just creates an alpha channel based on the color.
    *)
    Images := Driver.GetTexture('..\..\media\2ddemo.png');
    Driver.MakeColorKeyTexture(Images, Vector2DF(0, 0));


    (*
    To be able to draw some text with two different fonts, we first load
    them. Ok, we load just one. As the first font we just use the default
    font which is built into the engine. Also, we define two rectangles
    which specify the position of the images of the red imps (little flying
    creatures) in the texture.
    *)
    Font := Device.GetGUIEnvironment.GetBuildInFont;
    Font2 := Device.GetGUIEnvironment.GetFont('..\..\media\fonthaettenschweiler.bmp');

    (*
    Prepare a nicely filtering 2d render mode for special cases.
    *)
    MaterialPtr := Driver.GetMaterial2D;
    MaterialPtr^.FTextureLayer[0].BilinearFilter := True;
    MaterialPtr^.FAntiAliasing := EAAM_FULL_BASIC;

    (*
    Everything is prepared, now we can draw everything in the draw loop,
    between the begin scene and end scene calls. In this example, we are
    just doing 2d graphics, but it would be no problem to mix them with 3d
    graphics. Just try it out, and draw some 3d vertices or set up a scene
    with the scene manager and draw it.
    *)
    while (Device.Run and Assigned(Driver)) do
    begin
      if Device.IsWindowActive then
      begin
        time := Device.GetTimer.GetTime;
        Driver.BeginScene(True, True, [255, 120, 102, 136]);

        (*
        First, we draw 3 sprites, using the alpha channel we
        created with makeColorKeyTexture. The last parameter
        specifies that the drawing method should use this alpha
        channel. The last-but-one parameter specifies a
        color, with which the sprite should be colored.
        (255,255,255,255) is full white, so the sprite will
        look like the original. The third sprite is drawn
        with the red channel modulated based on the time.
        *)

        // draw fire & dragons background world
        Driver.Draw2DImage(Images, Vector2D(50, 50), IrrRect(0, 0, 324, 224),
          nil, IrrColor(255, 255, 255, 255), True);

        // draw flying imp
        if (time div 500 mod 2) <> 0 then
          ImpPtr := @Imp1
        else
          ImpPtr := @Imp2;
        Driver.Draw2DImage(Images, Vector2D(164, 125), ImpPtr^,
          nil, IrrColor(255, 255, 255, 255), True);

        // draw second flying imp with colorcylce
        Driver.Draw2DImage(Images, Vector2D(270, 105), ImpPtr^,
          nil, IrrColor(time mod 255, 255, 255, 255), True);

        (*
        Drawing text is really simple. The code should be self
        explanatory.
        *)

        // draw some text
        if Assigned(Font) then
        begin
          Font.Draw
          (
            'This demo shows that Irrlicht is also capable of drawing 2D graphics.',
            IrrRect(130, 10, 300, 50),
            IrrColor(255, 255, 255, 255)
          );
        end;

        // draw some other text
        if Assigned(Font2) then
        begin
          Font2.Draw
          (
            'Also mixing with 3D graphics is possible.',
            IrrRect(130, 20, 300, 60),
            IrrColor(time mod 255, time mod 255, 255, 255)
          );
        end;

        (*
        Next, we draw the Irrlicht Engine logo (without
        using a color or an alpha channel). Since we slightly scale
        the image we use the prepared filter mode.
        *)
        Driver.EnableMaterial2D(True);
        Driver.Draw2DImage(Images, IrrRect(10, 10, 108, 48),
          IrrRect(354, 87, 442, 118));
        Driver.EnableMaterial2D(False);

        (*
        Finally draw a half-transparent rect under the mouse cursor.
        *)
        m := Device.GetCursorControl.GetPosition^;
        Driver.Draw2DRectangle(IrrColor(255, 255, 255, 100),
          IrrRect(m.X - 20, m.Y - 20, m.X + 20, m.Y + 20));

        Driver.EndScene;
      end;

    end;

    Device.Drop;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
